#include "game.h"

MapSite::MapSite()
{

}

MapSite::~MapSite()
{

}

Room::Room(int roomNo)
{
    _roomNumber = roomNo;
}

Room::Room(const Room &other)
{
    _roomNumber = other._roomNumber;
    for(int i=0; i< 4; ++i)
        this->_side[i] = other._side[i];
}

MapSite *Room::GetSide(Direction d) const
{
    return _side[d];
}

void Room::SetSide(Direction d, MapSite * s)
{
    _side[d] = s;
}

void Room::Enter()
{

}

QString Room::type() const
{
    return "Room";
}

int Room::Id() const
{
    return _roomNumber;
}

Room *Room::Clone() const
{
    return new Room(*this);
}

void Room::Initialize(int n)
{
    _roomNumber = n;
}

MazeGame::MazeGame()
{

}

MazeGame::~MazeGame()
{

}

Maze *MazeGame::CreateMaze(MazeFactory &factory)
{
    Maze* aMaze = factory.MakeMaze();
    Room* r1 = factory.MakeRoom(0);
    Room* r2 = factory.MakeRoom(1);
    Door* aDoor = factory.MakeDoor(r1, r2);

    aMaze->AddRoom(r1);
    aMaze->AddRoom(r2);

    r1->SetSide(North, factory.MakeWall());
    r1->SetSide(East, aDoor);
    r1->SetSide(South, factory.MakeWall());
    r1->SetSide(West, factory.MakeWall());
    r2->SetSide(North, factory.MakeWall());
    r2->SetSide(East, factory.MakeWall());
    r2->SetSide(South, factory.MakePerson("Person"));
    r2->SetSide(West, aDoor);

    return aMaze;
}

Maze *MazeGame::CreateMaze()
{
    Maze* aMaze = MakeMaze();
    Room* r1 = MakeRoom(0);
    Room* r2 = MakeRoom(1);
    Door* aDoor = MakeDoor(r1, r2);

    aMaze->AddRoom(r1);
    aMaze->AddRoom(r2);

    r1->SetSide(North, MakeWall());
    r1->SetSide(East, aDoor);
    r1->SetSide(South, MakeWall());
    r1->SetSide(West, MakeWall());
    r2->SetSide(North, MakeWall());
    r2->SetSide(East, MakeWall());
    r2->SetSide(South, MakeWall());
    r2->SetSide(West, aDoor);

    return aMaze;
}

void Wall::Enter()
{

}

QString Wall::type() const
{
    return "Wall";
}

Wall *Wall::Clone() const
{
    return new Wall(*this);
}

Door::Door(Room *r1, Room *r2)
{
    _room1 = r1;
    _room2 = r2;
}

Door::Door(const Door & other)
{
    _room1 = other._room1;
    _room2 = other._room2;
}

void Door::Enter()
{

}

QString Door::type() const
{
    return "Door";
}

Room *Door::OtherSideFrom(Room * r)
{
    if(r == _room1) return _room2;
    else if(r == _room2) return _room1;
    return 0;
}

void Door::Initialize(Room * r1, Room * r2)
{
    _room1 = r1;
    _room2 = r2;
}

Door *Door::Clone() const
{
    return new Door(*this);
}

Maze::Maze()
{

}

Maze::~Maze()
{

}

Maze::Maze(const Maze &other)
{
    _rooms = other._rooms;
}

void Maze::AddRoom(Room *r)
{
    _rooms.append(r);
}

Room *Maze::RoomNo(int n) const
{
    if(n < _rooms.length())
        return _rooms.at(n);
    return 0;
}

int Maze::GetRoomSize() const
{
    return _rooms.length();
}

Maze *Maze::Clone() const
{
    return new Maze(*this);
}

MazeFactory::MazeFactory()
{

}

MazeFactory* MazeFactory::_instance = 0;

MazeFactory *MazeFactory::Instance()
{
    if(_instance == 0)
    {
        _instance = new MazeFactory;
    }
    return _instance;
}

MazeFactory::~MazeFactory()
{

}

MapSitePerson::MapSitePerson(QString n)
    :Person(n)
{

}

MapSitePerson2::MapSitePerson2(Person *p)
{
    _person = p;
}
